// Copyright (C) 2004-2007 MySQL AB
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as published by
// the Free Software Foundation
//
// There are special exceptions to the terms and conditions of the GPL 
// as it is applied to this software. View the full text of the 
// exception in file EXCEPTIONS in the directory of this software 
// distribution.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

using System;
using System.Data;
using System.Data.Common;

namespace MyLibrary.Data.MySQL.MySqlClient
{
    /// <include file='docs/MySqlTransaction.xml' path='docs/Class/*'/>
    public sealed class MySqlTransaction : DbTransaction
    {
        private IsolationLevel level;
        private MySqlConnection conn;
        private bool open;

        internal MySqlTransaction(MySqlConnection c, IsolationLevel il)
        {
            conn = c;
            level = il;
            open = true;
        }

        #region Properties

        /// <summary>
        /// Gets the <see cref="MySqlConnection"/> object associated with the transaction, or a null reference (Nothing in Visual Basic) if the transaction is no longer valid.
        /// </summary>
        /// <value>The <see cref="MySqlConnection"/> object associated with this transaction.</value>
        /// <remarks>
        /// A single application may have multiple database connections, each 
        /// with zero or more transactions. This property enables you to 
        /// determine the connection object associated with a particular 
        /// transaction created by <see cref="MySqlConnection.BeginTransaction()"/>.
        /// </remarks>
        public new MySqlConnection Connection
        {
            get { return conn; }
        }

        /// <summary>
        /// Specifies the <see cref="IsolationLevel"/> for this transaction.
        /// </summary>
        /// <value>
        /// The <see cref="IsolationLevel"/> for this transaction. The default is <b>ReadCommitted</b>.
        /// </value>
        /// <remarks>
        /// Parallel transactions are not supported. Therefore, the IsolationLevel 
        /// applies to the entire transaction.
        /// </remarks>
        public override IsolationLevel IsolationLevel
        {
            get { return level; }
        }

        protected override DbConnection DbConnection
        {
            get { return conn; }
        }

        #endregion

        /// <include file='docs/MySqlTransaction.xml' path='docs/Commit/*'/>
        public override void Commit()
        {
            if (conn == null || (conn.State != ConnectionState.Open && !conn.SoftClosed))
                throw new InvalidOperationException("Connection must be valid and open to commit transaction");
            if (!open)
                throw new InvalidOperationException("Transaction has already been committed or is not pending");
            MySqlCommand cmd = new MySqlCommand("COMMIT", conn);
            cmd.ExecuteNonQuery();
            open = false;
        }

        /// <include file='docs/MySqlTransaction.xml' path='docs/Rollback/*'/>
        public override void Rollback()
        {
            if (conn == null || (conn.State != ConnectionState.Open && !conn.SoftClosed))
                throw new InvalidOperationException("Connection must be valid and open to rollback transaction");
            if (!open)
                throw new InvalidOperationException("Transaction has already been rolled back or is not pending");
            MySqlCommand cmd = new MySqlCommand("ROLLBACK", conn);
            cmd.ExecuteNonQuery();
            open = false;
        }
    }
}
